查看原文
其他

图解线程生命周期

Java4ye Java4ye 2022-09-04

小伙伴们晚上好呀~  😋

「4ye」 这期来和大家分享下这个 「Java线程的生命周期」 ( •̀ ω •́ )y

img

注意这里特意指明了是 「Java」

img

因为线程这东西是 「操作系统调度的最小单元」

所以在操作系统中肯定也有它的生命周期呀,各种状态呀~

让我们一起往下看看叭👇

操作系统线程生命周期

image

如图所示~ ,这些也被称为 「通用线程状态」

分为五种:

「初始状态、可运行状态、运行状态、休眠状态和终止状态」

初始状态

这里仅仅是 编程语言上的创建,操作系统中并没有创建线程。

可运行状态

操作系统中已经成功创建线程了,「等待获取CPU时间片」

运行状态

还记得之前讲到进程的调度算法吗😄,线程是进程的基本组成单元,当进程被调度时,也意味着对应的线程被执行啦~  (操作系统从就绪队列中取出任务,然后为其分配一定的时间片去执行~)

这里线程就变成运行状态了 ,正在 「消耗CPU时间片」

休眠状态

比如 阻塞IO 或者 等待某个事件时 ,就会导致线程的状态变成休眠状态,此时 CPU 会浪费在等待上

要等到IO结束,或着等到了某个事件,线程才会变成可运行状态

终止状态

线程已经执行完了,或者出现异常也会进入终止状态,此时不能再切换成其他状态了,「线程的生命周期结束了」


简单介绍完这个操作系统的生命周期,让我们来看看这个 java中线程的生命周期叭~

Java线程的生命周期

直接上图~ 

image

Thread 源码中,可以发现枚举类 State  中定义了下面几种状态

image
public enum State {
 NEW,
 RUNNABLE,
 BLOCKED,
 WAITING,
 TIMED_WAITING,
 TERMINATED;
}

NEW

对应创建线程,未调用 start()  方法时候的状态

Thread thread = new Thread();

RUNNABLE

调用了 start()  方法的线程会进入该状态,

Thread thread = new Thread();
thread.start();

BLOCKED

当进入 Synchronized 同步代码块或者方法时,没有获取到锁的🔒,就会进入阻塞状态,此时线程会进入该锁对象的 「同步队列」 中,这里也十分有趣!哈哈哈 后面写这个 [[ Synchronized 锁的实现原理]] 时带大家一起看看😝

img

获取到锁后就进入  RUNNABLE 状态啦。

public class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        hello();
    }

    public void hello() {
        synchronized ("Java4ye") {
            System.out.println(Thread.currentThread().getName() + "  : Java4ye");
            while (true) {
            }
        }
    }


    public static void main(String[] args) {
        new MyThread("A").start();
        new MyThread("B").start();
        new MyThread("C").start();
    }

}

效果:

image

WAITING

这里调用 Object 类的 wait 方法 或者 Thread 类的 join 方法,将会导致线程 「释放锁」,进入该对象的 「等待队列」,同时线程变为等待状态。

或者使用 LockSupport.park(); 也会进入 WAITING 状态 。

这个 LockSupport 是一个很灵活的「线程工具类」,嘿嘿 后面也会单独介绍这个  [[LockSupport ]] 😝

img

比如

public void hello() {
    synchronized ("Java4ye") {
        System.out.println(Thread.currentThread().getName() + "  : Java4ye");
        try {
            "Java4ye".wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("End");
    }
}

当调用  Object 类的 notify  或者 notifyAll 方法时,线程会重新进入RUNNABLE 状态。

调用 LockSupport.unpark(myThread);  myThread线程会重新进入 RUNNABLE 状态。

TIMED_WAITING

这里就比较简单啦,在上面的等待方法中加一个时间~

比如 Object.wait(long) ,  Thread.join(long) 等等 如上图所示~

最主要的是   Thread.sleep(long) 方法不会释放锁 ,Object.wait(long) 会释放锁资源

时间到了之后,线程重新进入  RUNNABLE 状态 ,

TERMINATED

线程执行完成,就进入该状态了,不能再转成其他状态了

总结

对比下 「操作系统和Java中线程的生命周期」 ,可以发现

  1. 「操作系统的可运行状态和运行状态对应 Java 中的 Runnable 状态」
  2. 「操作系统的休眠状态,对应 Java 中的三种状态  BLOCKED, WAITING, TIMED_WAITING」

如下~

image

回顾

嘿嘿 到这里 「4ye」 已经和小伙伴们分享这四个啦 冲冲冲!😝

image

「我是 4ye 我们下期再见啦 ヾ( ̄▽ ̄)Bye~~ Bye ~~」


Java中的锁居然有这么多!


面试官:线程有几种创建方式?


时间片,上下文,调度算法等知识点~


带你从CPU看到进程~(硬核)


欢迎关注,交个朋友呀!!( •̀ ω •́ )y







您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存